#include <stdio.h>
#include <math.h>

#include "digikey_choices.h"

#define VOUTPUT 3.3
#define MAXTOTALRESISTANCE 1.0e6

///////////////////////////////////////////////////////////////////////////////
// Local prototypes

double voutCalc(double top, double bottom);
double inductorCurrentMax(double inductor, double vout, double vin);


///////////////////////////////////////////////////////////////////////////////
// Main function
int main (int argc, const char * argv[]) {
    printf("Calculating voltage setting resistors for TPS62410\n");
		
		int RSIZE = rdigikeysize;

		double vcc[RSIZE][RSIZE];
		double vccErr[RSIZE][RSIZE];
		
		int rowsLength = RSIZE;
		int columnsLength = RSIZE;
		
		int rows = 0;
		int columns = 0;
		
		// Some bogus large error
		double errorMin = 10.0;
		
		// Calculated error
		double error = 0;
		
		int bestTopResistorIndex = 0;
		int bestBottomResistorIndex = 0;
		
		for (rows = 0; rows < rowsLength; rows++)
		{
			// Print a new line for each row
				printf("\n");
			
			for (columns = 0; columns < columnsLength; columns++)
			{
				// Voltage output using select resistors
				vcc[rows][columns] = voutCalc(rdigikey[rows],rdigikey[columns]);
				
				// Error array
				vccErr[rows][columns] = VOUTPUT - vcc[rows][columns];
				
				error = vccErr[rows][columns];
				if (error < 0)
						error = -1 * vccErr[rows][columns];

				if (error < errorMin && (rdigikey[rows] + rdigikey[columns]) < MAXTOTALRESISTANCE) {
#ifdef DEBUG
					printf("\nERRORMIN %2.4f at row %i and column %i \n",error,rows,columns);	
					printf("Rtop: %2.2f and Rbottom: %2.2f \n",rdigikey[rows],rdigikey[columns]);
#endif
					bestTopResistorIndex = rows;
					bestBottomResistorIndex = columns;
					errorMin = error;		
				}			
#ifdef DEBUG					
				printf("%2.2f ",vcc[rows][columns]);
#endif
			}
		}
		
		printf("\n\nIdeal resistor combination is as follows: \n");
		printf("\tIndex %i Rtop = %2.2f ohms \n",bestTopResistorIndex,rdigikey[bestTopResistorIndex]);
		printf("\tIndex %i Rbottom = %2.2f ohms \n",bestBottomResistorIndex,rdigikey[bestBottomResistorIndex]);
		printf("\t\tVout = %f \n",voutCalc(rdigikey[bestTopResistorIndex],rdigikey[bestBottomResistorIndex]));	
		
		// Inductor calculations
		printf("\nMax inductor current under static loads is ");
		printf("%2.3f Amps\n",inductorCurrentMax(2.2e-6,VOUTPUT,5.0));
		
    return 0;
}

///////////////////////////////////////////////////////////////////////////////
// Voltage output calculation
double voutCalc(double top, double bottom)
{
	double result;
	double vref = 0.6;
	
	result = vref * (1 + top/bottom);
	
	return result;
}

///////////////////////////////////////////////////////////////////////////////
// Inductor choice selection

double inductorCurrentMax(double inductor, double vout, double vin)
{
	double result;
	double f = 2.25e6; // 2.25MHz
	
	result = vout - (1 - (vout/vin)) / (inductor * f);

	return result;
}
